package com.mascotikas.client.widgets;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.HasHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.TextBox;

import com.mascotikas.client.events.GalleryUpdatedEvent;
import com.mascotikas.client.events.GalleryUpdatedEventHandler;
import com.mascotikas.client.jdos.LoginInfo;
import com.mascotikas.client.services.IUserImageService;
import com.mascotikas.client.services.IUserImageServiceAsync;
import com.mascotikas.shared.Tag;
import com.mascotikas.shared.UploadedImage;
import com.reveregroup.gwt.imagepreloader.FitImage;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.layout.VStack;

public class HtmlFlowOverlay extends HTMLFlow  implements HasHandlers  {

    IUserImageServiceAsync imageService = GWT.create(IUserImageService.class);
    private HandlerManager handlerManager;
    Button deleteButton;
    FitImage image;
    Label timestamp;
    VStack tagPanel;
    VStack pnlHtmlFlow;
    protected UploadedImage uploadedImage;
    LoginInfo loginInfo;

    public HtmlFlowOverlay(final UploadedImage uploadedImage, LoginInfo loginInfo) {
        handlerManager = new HandlerManager(this);

        this.uploadedImage = uploadedImage;
        this.loginInfo = loginInfo;
        timestamp = new Label("Created at:" + uploadedImage.getCreatedAt());
        deleteButton = new Button("Delete Imagen");
        final HtmlFlowOverlay overlay = this;
        deleteButton.addClickHandler(new com.google.gwt.event.dom.client.ClickHandler() {

            public void onClick(com.google.gwt.event.dom.client.ClickEvent event) {
                imageService.deleteImage(uploadedImage.getKey(),
                        new AsyncCallback<Void>() {

                            @Override
                            public void onSuccess(Void result) {
                                GalleryUpdatedEvent event = new GalleryUpdatedEvent();
                                fireEvent(event);
                                overlay.removeFromParent();
                            }

                            @Override
                            public void onFailure(Throwable caught) {
                                Window window = new Window();
                                window.addChild(new Label("Can't delete"));
                                window.show();
                            }
                        });
            }
        });


        image = new FitImage(uploadedImage.getServingUrl(), 600, 600);
        image.addClickHandler(new com.google.gwt.event.dom.client.ClickHandler() {

            public void onClick(com.google.gwt.event.dom.client.ClickEvent e) {
                Element imageElement = e.getRelativeElement();
                int x = e.getRelativeX(imageElement);
                int y = e.getRelativeY(imageElement);
                // Window.alert("X: " + x + " Y: "+ y);
                TagDialog tagDialog = new TagDialog(image, x, y);
                tagDialog.showAndFocus();
            }
        });


        tagPanel = new VStack();
        pnlHtmlFlow = new VStack();

        if (loginInfo != null && (loginInfo.getId().equals(uploadedImage.getOwnerId()))) {
            deleteButton.setVisible(true);
        } else {
            deleteButton.setVisible(false);
        }

        // Now let's fetch the tags
        imageService.getTagsForImage(uploadedImage,
                new AsyncCallback<List<Tag>>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        Window window = new Window();
                        window.addChild(new Label("Can't delete"));
                        window.show();

                    }

                    @Override
                    public void onSuccess(List<Tag> result) {
                        // TODO Auto-generated method stub
                        for (Tag tag : result) {
                            tagPanel.addChild(new HTMLFlow(tag.getBody()));
                        }

                    }
                });

        pnlHtmlFlow.addChild(image);
        pnlHtmlFlow.addChild(timestamp);
        pnlHtmlFlow.addChild(tagPanel);
        pnlHtmlFlow.addChild(deleteButton);
        

        addChild(pnlHtmlFlow);
    }

    private class TagDialog extends DialogBox {

        private TextBox textBox;

        public TagDialog(Image image, final int x, final int y) {

            // Set the dialog box's caption.
            setText("Tagging X: " + x + " Y: " + y);

            setAutoHideEnabled(true);

            int dialogX = image.getAbsoluteLeft() + x;
            int dialogY = image.getAbsoluteTop() + y;

            setPopupPosition(dialogX, dialogY);

            HorizontalPanel tagPanel = new HorizontalPanel();

            textBox = new TextBox();
            tagPanel.add(textBox);

            textBox.addKeyPressHandler(new KeyPressHandler() {

                @Override
                public void onKeyPress(KeyPressEvent event) {
                    if (event.getCharCode() == KeyCodes.KEY_ENTER) {
                        saveTag(x, y, textBox);
                    }

                }
            });

            Button ok = new Button("Tag");
            ok.addClickHandler(new com.google.gwt.event.dom.client.ClickHandler() {

                public void onClick(com.google.gwt.event.dom.client.ClickEvent event) {
                    saveTag(x, y, textBox);
                }
            });

            tagPanel.add(ok);

            setWidget(tagPanel);

        }

        public void showAndFocus() {
            show();
            textBox.setFocus(true);
        }

        private void saveTag(final int x, final int y, final TextBox textBox) {
            Tag tag = new Tag();

            // TODO: Change this to also pass the Image
            tag.setPhotoKey(uploadedImage.getKey());
            tag.setBody(textBox.getValue());
            tag.setX(x);
            tag.setY(y);

            imageService.tagImage(tag, new AsyncCallback<String>() {

                @Override
                public void onFailure(Throwable caught) {
                    // TODO Auto-generated method stub
                }

                @Override
                public void onSuccess(String result) {
                    TagDialog.this.hide();
                }
            });
        }
    }

    @Override
    public void fireEvent(GwtEvent<?> event) {
        handlerManager.fireEvent(event);
    }

    public HandlerRegistration addGalleryUpdatedEventHandler(
            GalleryUpdatedEventHandler handler) {
        return handlerManager.addHandler(GalleryUpdatedEvent.TYPE, handler);
    }
}
